import type { AxiosInstance, InternalAxiosRequestConfig } from 'axios';
import axios from 'axios';
import type { IAxiosRequestConfig } from './type';

class MLRequest {
  instance: AxiosInstance;
  config?: IAxiosRequestConfig;

  constructor(config: IAxiosRequestConfig) {
    this.instance = axios.create({
      ...config,
    });

    if (config && config.interceptors) {
      // 局部拦截器配置
      this.instance.interceptors.request.use(
        config.interceptors.requestSuccessFn,
        config.interceptors.requestFailureFn,
      );
      this.instance.interceptors.response.use(
        config.interceptors.responeseSuccessFn,
        config.interceptors.responeseFailureFn,
      );
    } else {
      // 全局拦截器配置
      this.instance.interceptors.request.use(
        (req) => {
          console.log('全局请求成功的拦截');
          return req;
        },
        (err) => {
          console.log('全局请求失败的拦截');
          return err;
        },
      );
      this.instance.interceptors.response.use(
        (res) => {
          console.log('全局响应成功拦截');
          return res.data;
        },
        (err) => {
          console.log('全局请求失败的拦截');
          return err;
        },
      );
    }
  }

  //二次封装request
  request<T = any>(config: IAxiosRequestConfig) {
    if (config.interceptors?.requestSuccessFn) {
      // 有请求拦截就使用
      // 这里发现request的config和requestSuccessFn的config类型有冲突，强制转化了一下
      config = config.interceptors.requestSuccessFn(config as any as InternalAxiosRequestConfig);
    }

    return new Promise<T>((resolve, reject) => {
      //响应成功的拦截我可以用promose劫持
      this.instance
        .request(config)
        .then((res) => {
          //这里进行请求的响应成功拦截
          if (config.interceptors?.responeseSuccessFn) {
            res = config.interceptors?.responeseSuccessFn(res);
          }
          resolve(res as T);
        })
        .catch((err) => {
          //这里进行请求的响应失败拦截
          if (config.interceptors?.responeseFailureFn) {
            err = config.interceptors?.responeseFailureFn(err);
          }
          reject(err);
        });
    });
  }

  get<T = any>(config: IAxiosRequestConfig) {
    return this.request<T>({ ...config, method: 'GET' });
  }

  post<T = any>(config: IAxiosRequestConfig) {
    return this.request<T>({ ...config, method: 'POST' });
  }
}

export default MLRequest;
